package it.trekker.map;

import it.trekker.R;
import android.content.Context;
import android.content.Intent;
import android.graphics.Point;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import com.google.android.maps.GeoPoint;
import com.google.android.maps.MapView;
import com.google.android.maps.OverlayItem;

public class PhotoItemizedOverlay extends MyItemizedOverlay {
	
	private static final String TAG = PhotoItemizedOverlay.class.getSimpleName();
	
	public static final int CENTER = 0;
	public static final int CENTER_BOTTOM = 1;
	
	private Context context;
	private MapView mapView;
	private OverlayItem selectedItem = null;
	private Drawable marker;
	private MapPopupView<OverlayItem> photoPopup = null;
	private View clickRegion;
	
	
	public PhotoItemizedOverlay(Context context, MapView mapView, Drawable marker) {
		super(boundCenterBottom(marker));
		this.context = context;
		this.marker = marker;
		this.mapView = mapView;
		
		populate();
	}

	
	private boolean handled;
	
	@Override
	protected boolean onTap(int index) {
		
		handled = true;
		
//		if(checkIfClosePhotoExist(index)) {
//			mapView.getController().setZoom(21);	// zoom between 1 and 21
//		}

		setLastFocusedIndex(index);
		selectedItem = createItem(index);

		moveTo(selectedItem.getPoint());

		createAndDisplayPopup();

		setFocus(selectedItem);

		return true;
	}
	
	
	@Override
	public boolean onTap(GeoPoint p, MapView mapView) {
		
		hidePopupView();
		
		return super.onTap(p, mapView);
	}

	
	public boolean checkIfClosePhotoExist(int index) {
		
		OverlayItem currentItem = createItem(index);
		
		Point currentPoint = new Point();
        mapView.getProjection().toPixels(currentItem.getPoint(), currentPoint);
		
        boolean hit = false;
        
		for(int i=0 ; (i<size() && !hit) ; i++) {
			if(i != index) {
				OverlayItem item = getItem(i);
				Point itemPoint = new Point();
				mapView.getProjection().toPixels(item.getPoint(), itemPoint);
				if(hitTest(currentItem, marker, currentPoint.x-itemPoint.x, currentPoint.y-itemPoint.y)) {
					hit = true;
				}
			}
		}
		
		return hit;
	}
	
	
	@Override
	protected boolean hitTest(OverlayItem overlayItem, Drawable drawable, int x, int y) {
	    Rect bounds = drawable.getBounds();
	    int newLeft = bounds.left - (bounds.centerX() - bounds.left); 
	    int newTop = bounds.top - (bounds.centerY() - bounds.top);
	    Rect square = new Rect(newLeft, newTop, bounds.width()*2, bounds.height()*2);
	    return square.contains(x, y);
	}

	
	
	private OverlayItem nextThumbnail() {
		return nextItem(selectedItem);
	}
	
	
	private OverlayItem prevThumbnail() {
		return prevItem(selectedItem);
	}
	
	
	private void hidePopupView() {
		if(photoPopup != null)
			photoPopup.setVisibility(View.GONE);
	}
	
	
	private void moveTo(GeoPoint point) {
		mapView.getController().animateTo(point);
	}

	
	private void createAndDisplayPopup() {
		
		boolean isRecycled;
		
		if(photoPopup == null) {
			photoPopup = new MapPopupView<OverlayItem>(context);
			clickRegion = photoPopup.findViewById(R.id.inner_layout);
//			clickRegion.setOnClickListener(createPhotoOnClickListener());
			clickRegion.setOnTouchListener(createOnTouchListener());
			isRecycled = false;
		}
		else {
			isRecycled = true;
		}
		
		photoPopup.setVisibility(View.GONE);
		
		if(selectedItem != null)
			photoPopup.setData(selectedItem);
		
		GeoPoint point = selectedItem.getPoint();
		MapView.LayoutParams params = new MapView.LayoutParams(
				LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, point,
				MapView.LayoutParams.TOP|MapView.LayoutParams.CENTER);
		params.mode = MapView.LayoutParams.MODE_MAP;
		params.y -= 10;
		
		photoPopup.setVisibility(View.VISIBLE);
		
		if(isRecycled)
			photoPopup.setLayoutParams(params);
		else
			mapView.addView(photoPopup, params);
	}


	private void launchImageViewer(String snippet) {
		Intent intent = new Intent();
		intent.setAction(android.content.Intent.ACTION_VIEW);
		intent.setDataAndType(Uri.parse("file://" + snippet), "image/jpg");
		context.startActivity(intent);
	}
	
	
	private static final int SCROLL_RIGHT = 0;
	private static final int SCROLL_LEFT = 1;
	
	private void handleScroll(int direction) {
		switch(direction) {
			case SCROLL_LEFT:
				selectedItem = nextThumbnail();
				break;
			case SCROLL_RIGHT:
				selectedItem = prevThumbnail();
				break;
		}
		createAndDisplayPopup();
		setFocus(selectedItem);
		moveTo(selectedItem.getPoint());
	}

	
	
	
	
	//*******************************************************************//
	//**************************** Listeners ****************************//
	//*******************************************************************//
	
	
	private View.OnClickListener createPhotoOnClickListener() {
		return new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				launchImageViewer(selectedItem.getSnippet());
			}
		};
	}

	
	private GestureDetector createGestureDetector() {
		return new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
			
			private static final int MIN_DISTANCE = 20;

			@Override
			public boolean onDown(MotionEvent e) {
				return true;
			}
			
			@Override
			public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) {

				int direction = (int) (e1.getX() - e2.getX());

				if (Math.abs(direction) > MIN_DISTANCE) {
					int scrollDirection;
					
		            if (direction > 0) {
		            	scrollDirection = SCROLL_LEFT;
		            } 
		            else {
		            	scrollDirection = SCROLL_RIGHT;
		            }
		            
		            handleScroll(scrollDirection);
		            
		            return true;
		        } 
		        else {
		            return false;
		        }
		    }

		});
	}
	
	
	private View.OnTouchListener createOnTouchListener() {
		
		final GestureDetector gestureDetector = createGestureDetector();
		
		return new View.OnTouchListener() {
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				
				if(gestureDetector.onTouchEvent(event)) {
					return true;
				}
				
				if(event.getAction() == MotionEvent.ACTION_UP) {
					launchImageViewer(selectedItem.getSnippet());
				}
				
				return false;
			}
		};
	}
}
